import { Body, Controller, Get, Param, Post, Query, UseGuards } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { ApiTags } from "@nestjs/swagger";
import { V2ApplyService } from "./v2.apply.service";
import { CurrentUser } from "src/user/user.decorator";
import { UserSys } from "src/user/userSys.entity";
import { FindOptionsWhere, In, IsNull, Not } from "typeorm";
import { ApplicationStatus, V2Apply } from "./v2.apply.entity";
import { ApplyUserStatus, V2ApplyLog } from "./v2.apply.log.entity";
import { RoleEnum } from "src/role/role.enum";
import { WorkflowType } from "./v2.apply.workflow.entity";


@Controller("api/v2/apply")
@ApiTags("v2申请")
@UseGuards(AuthGuard("jwt"))
export class V2ApplyContainer {
    constructor(
        private readonly applyService: V2ApplyService
    ) { }

    @Post("add")
    add(
        @Body() {
            type,
            data,
            comment
        },
        @CurrentUser() user: UserSys
    ) {
        return this.applyService.create(type, user, JSON.stringify(data), comment);
    }

    @Get("getmine")
    async getmine(
        @CurrentUser() user: UserSys
    ) {
        const data = await this.applyService.apply.find({
            where: {
                user: {
                    id: user.id
                }
            },
            relations: ["current"],
            order: {
                id: "desc"
            }
        })
        const types = [...data.reduce((set, { name }) => {
            set.add(name);
            return set;
        }, new Set<string>())]
        const workflows = {};
        for (const name of types) {
            workflows[name] = this.applyService.list2tree(await this.applyService.workflow.find({ where: { name }, relations: ["next"] }))
        }
        return data.map((e) => ({
            ...e,
            workflow: workflows[e.name]
        }))
    }

    @Get("getworkflow")
    getworkflow(
        @CurrentUser() user: UserSys,
        @Query("type") type?: string
    ) {
        const where: FindOptionsWhere<V2ApplyLog> = {}
        if (!!type) where.name = type
        if (user.role !== RoleEnum.boos) {
            where.apply = { system: { id: user.system.id } }
        }
        where.workflow = [{
            type: WorkflowType.user,
            userRole: user.role
        }]

        if (!!user.dept) {
            where.workflow.push({
                type: WorkflowType.dept,
                deptRole: user.dept?.deptRole
            })
        }
        return this.applyService.applylog.find({
            order: {
                id: "desc"
            },
            where: [where, { workUser: { id: user.id }, name: type }],
            relations: ["workflow", "apply", "workUser", "user", "user.dept", "user.user", "system"]
        })
    }

    @Post("dellog")
    async dellog(
        @Body() { ids }
    ) {
        return this.applyService.applylog.delete({
            id: In(ids),
            status: Not(ApplyUserStatus.待审批)
        })
    }

    @Get("/:id/del")
    async del(
        @Param("id") id
    ) {
        const entity = await this.applyService.apply.findOne({ where: { id } })
        await this.applyService.applylog.delete({
            apply: { id: entity.id },
            status: ApplyUserStatus.待审批
        })
        await this.applyService.apply.delete({
            id: entity.id
        })
    }

    @Post("set")
    async set(
        @CurrentUser() user: UserSys,
        @Body() { ids, operation, comment }
    ) {
        const bool = operation == "true"
        const entitys = (await this.applyService.applylog.find({
            where: {
                id: In(ids),
            },
            relations: ["workflow", "user", "apply", "apply.current", "apply.user", "apply.user.system", "apply.current.next"]
        })).filter(e => e.workflow.id === e.apply.current.id)
        for (const entity of entitys) {
            entity.comment = comment
            entity.workUser = user
            if (bool) {
                const next = entity.apply.current.next
                entity.status = ApplyUserStatus.已通过
                entity.apply.current = next;
                if (!next || next.userRole === RoleEnum.boos) {
                    //结束
                    entity.apply.status = ApplicationStatus.finished
                    await this.applyService.finish(entity.apply)
                } else {
                    await this.applyService.applylog.save(
                        this.applyService.applylog.create({
                            apply: entity.apply,
                            workflow: next,
                            user: entity.user,
                            data: entity.data,
                            comment: entity.comment,
                            name: entity.name,
                            system: entity.system,
                            createAt: entity.createAt
                        })
                    )
                }
            } else {
                entity.status = ApplyUserStatus.拒绝申请
                entity.apply.status = ApplicationStatus.rejected;
            }
            await this.applyService.applylog.save(entity)
            await this.applyService.apply.save(entity.apply)
        }

    }


}